package com.chuangke.file.controller;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.chuangke.common.constant.FileConstants;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.http.HttpResult;
import com.chuangke.common.utils.FileUtils;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.common.utils.ZipUtils;
import com.chuangke.file.domain.FileAffixOptDTO;
import com.chuangke.file.domain.FileCategoryDTO;
import com.chuangke.file.domain.FileDeleteDTO;
import com.chuangke.file.domain.FileOperateDTO;
import com.chuangke.file.domain.FileOptDTO;
import com.chuangke.file.domain.FileRestoreDTO;
import com.chuangke.file.domain.FileShareDTO;
import com.chuangke.file.domain.GetAllChildrenDTO;
import com.chuangke.file.domain.PermissionSaveDTO;
import com.chuangke.file.manager.FileAuthManager;
import com.chuangke.file.model.FileChunk;
import com.chuangke.file.model.FileInfo;
import com.chuangke.file.model.FileType;
import com.chuangke.file.service.FileDownloadHistoryService;
import com.chuangke.file.service.FileInfoService;
import com.chuangke.file.service.FileQueryService;
import com.chuangke.file.service.FileTransferService;
import com.chuangke.system.annotation.OptLogDoc;
import com.chuangke.system.enums.LogBisType;
import com.chuangke.system.enums.LogOptType;

/**
 * @Description 文件管理
 * @author stm
 * @date 2019年2月22日 下午4:10:09
 */
@RestController
@RequestMapping("file")
public class FileController {

	@Autowired
	private FileTransferService fileTransferService;
	@Autowired
	private FileInfoService fileInfoService;
	@Autowired
	private FileDownloadHistoryService fileDownloadHistoryService;
	@Autowired
	private FileQueryService fileQueryService;
	@Autowired
	private FileAuthManager fileAuthManager;

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/query")
	public HttpResult query(@RequestBody Map<String, Object> pageQuery) {
		return HttpResult.ok(fileQueryService.query(new CkPageQuery(pageQuery)));
	}

	/**
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/load")
	public HttpResult loadFile(@RequestParam String dbankId, @RequestParam String fileId) {
		//先把文件加载出来，否则通过评论或者动态没法打开
		FileInfo file = fileQueryService.load(fileId) ;
		fileAuthManager.checkView(SecurityUtils.getUserId(), file.getDbankId(), fileId);
		return HttpResult.ok(file);
	}

	/**
	 * @param parentId
	 * @param dbankId
	 * @param delFlag
	 * @param fileType all:所有文件类型
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/list")
	public HttpResult list(@RequestParam String parentId, @RequestParam String dbankId, @RequestParam String delFlag,
			@RequestParam String fileType, @RequestParam(required = false) String order) {
//		fileAuthManager.checkView(SecurityUtils.getUserId(), dbankId);
		if (parentId == null) {
			parentId = FileConstants.FILE_ROOT_PARENT;
		}
		return HttpResult.ok(fileQueryService.listFiles(parentId, dbankId, delFlag, fileType, order));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/listauthshare")
	public HttpResult listAuthShare(@RequestParam String dbankId, @RequestParam(required = false) String order) {
		return HttpResult.ok(fileQueryService.listShareFiles(dbankId, SecurityUtils.getUserId(), order));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/listchildren")
	public HttpResult listOwnChildren(@RequestBody GetAllChildrenDTO param) {
		return HttpResult.ok(fileQueryService.getChildrenFileIds(param.getFiles()));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/myfocus")
	public HttpResult myFocus(@RequestBody Map<String, Object> pageQuery) {
		return HttpResult.ok(fileQueryService.pageFocus(new CkPageQuery(pageQuery)));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/mypublish")
	public HttpResult myPublish(@RequestBody Map<String, Object> pageQuery) {
		return HttpResult.ok(fileQueryService.pagePublish(new CkPageQuery(pageQuery)));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/toppublish")
	public HttpResult topPublish(@RequestBody Map<String, Object> pageQuery) {
		return HttpResult.ok(fileQueryService.pageTopPublish(new CkPageQuery(pageQuery)));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/myshare")
	public HttpResult myshare(@RequestBody Map<String, Object> pageQuery) {
		return HttpResult.ok(fileQueryService.pageShare(new CkPageQuery(pageQuery)));
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "上传了文档", optType = LogOptType.UPLOAD, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping("/upload")
	public HttpResult singleUpload(String dbankId, FileChunk fileChunk) {
		fileAuthManager.checkUpload(SecurityUtils.getUserId(), fileChunk.getDbankId(), fileChunk.getParentId());
		FileInfo fileInfo = fileTransferService.upload(fileChunk);
		return HttpResult.ok(fileInfo);
	}

	@PreAuthorize("hasAuthority('login:action')")
	@OptLogDoc(objId = "#id", objCarrierId = "data.dbankId", name = "上传了新的版本", optType = LogOptType.UPLOAD, objType = LogBisType.file)
	@PostMapping("/reupload")
	public HttpResult uploadFileRepetition(String id, String dbankId, MultipartFile file) {
		fileAuthManager.checkUpload(SecurityUtils.getUserId(), dbankId, id);
		FileInfo fileInfo = fileTransferService.reUpload(file, id);
		return HttpResult.ok(fileInfo);
	}

	@OptLogDoc(objId = "#id", objCarrierId = "#dbankId", name = "下载了文档", optType = LogOptType.DOWNLOAD, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping("/download/{id}/{signId}")
	public void downloadFile(@PathVariable String id, @PathVariable String signId,
			@RequestParam(required = false) String dbankId, HttpServletResponse response) {
		fileAuthManager.checkDownload(SecurityUtils.getUserId(), dbankId, id);

		byte[] fileBytes = fileTransferService.download(id, signId);
		FileUtils.download(response, fileBytes);
	}

	@PreAuthorize("hasAuthority('login:action')")
	@OptLogDoc(objId = "#id", objCarrierId = "#dbankId", name = "查看了文档", optType = LogOptType.VIEW, objType = LogBisType.file)
	@GetMapping("/view")
	public void view(@RequestParam String id, @RequestParam String signId,
			@RequestParam(required = false) String dbankId, @RequestParam(required = false) String fullfilename,
			HttpServletResponse response) {
		FileUtils.download(response, fileTransferService.download(id, signId));
	}

	@GetMapping("/downloadbatch")
	public void downloadFileBatch(HttpServletResponse response) throws IOException {
		List<String> ids = Arrays.asList("766375421708075008");
		Map<String, byte[]> map = fileTransferService.download(ids);
		ZipUtils.downloadFileZip(response, "piliang", map);
		System.out.println("************8");
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "创建了目录", optType = LogOptType.CREATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/createdir")
	public HttpResult createDir(@RequestBody FileInfo record) {
		fileAuthManager.checkEdit(SecurityUtils.getUserId(), record.getDbankId(), record.getId());

		return HttpResult.ok(fileInfoService.createDir(record));
	}

//	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "上传了附件", optType = LogOptType.UPLOAD, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping("/uploadAffix")
	public HttpResult taskFileUpload(MultipartFile file) {
		String parentId = "0";
		FileInfo fileInfo = fileTransferService.upload(file, FileConstants.SYSTEM_DBANK_ID, parentId);
		return HttpResult.ok(fileInfo);
	}

	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/findFileHistoryVersion")
	public HttpResult findFileHistoryVersion(@RequestParam String id, @RequestParam String dbankId) {
		if (id == null) {
			id = "";
		}
		return HttpResult.ok(fileQueryService.listHistory(id));
	}

	@OptLogDoc(objId = "data.![id]", objCarrierId = "data.![dbankId]", name = "删除了文档", optType = LogOptType.DELETE_SOFT, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/delete")
	public HttpResult delete(@RequestBody FileDeleteDTO param) {
		for (String fileId : param.getFiles()) {
			fileAuthManager.checkDelete(SecurityUtils.getUserId(), param.getDbankId(), fileId);
		}
		return HttpResult.ok(fileInfoService.deleteToRecycle(param));
	}

	@OptLogDoc(objId = "data.![id]", objCarrierId = "data.![dbankId]", name = "恢复了文档", optType = LogOptType.DELETE_SOFT, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/restore")
	public HttpResult restore(@RequestBody FileRestoreDTO param) {
		return HttpResult.ok(fileInfoService.restoreFromRecycle(param));
	}

	@OptLogDoc(objId = "data.![id]", objCarrierId = "data.![dbankId]", name = "彻底删除了文档", optType = LogOptType.DELETE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/deleteFromTrash")
	public HttpResult deleteFromTrash(@RequestBody FileDeleteDTO param) {
		return HttpResult.ok(fileInfoService.deleteShift(param));
	}

	@OptLogDoc(objId = "data.![id]", objCarrierId = "data.![dbankId]", name = "清空彻底删除了文档", optType = LogOptType.DELETE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/cleanrecycle")
	public HttpResult cleanRecycle(@RequestBody String dbankId) {
		return HttpResult.ok(fileInfoService.cleanRecycle(dbankId));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@OptLogDoc(objId = "#fileOperateRequest.idList", objCarrierId = "#fileOperateRequest.dbankId", name = "移动了文档", optType = LogOptType.MOVE, objType = LogBisType.file)
	@PostMapping(value = "/move")
	public HttpResult move(@RequestBody FileOperateDTO fileOperateRequest) {
		fileAuthManager.checkManage(SecurityUtils.getUserId(), fileOperateRequest.getDbankId(),
				fileOperateRequest.getParentId());
		for (String fileId : fileOperateRequest.getIdList()) {
			fileAuthManager.checkManage(SecurityUtils.getUserId(), fileOperateRequest.getDbankId(), fileId);
		}
		fileInfoService.move(fileOperateRequest.getDbankId(), fileOperateRequest.getIdList(),
				fileOperateRequest.getParentId());
		return HttpResult.ok();
	}

	@OptLogDoc(objId = "#fileOperateRequest.idList", objCarrierId = "#fileOperateRequest.dbankId", name = "复制了文档", optType = LogOptType.MOVE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/copy")
	public HttpResult copy(@RequestBody FileOperateDTO fileOperateRequest) {
		fileAuthManager.checkManage(SecurityUtils.getUserId(), fileOperateRequest.getDbankId(),
				fileOperateRequest.getParentId());
		for (String fileId : fileOperateRequest.getIdList()) {
			fileAuthManager.checkManage(SecurityUtils.getUserId(), fileOperateRequest.getDbankId(), fileId);
		}
		fileInfoService.copy(fileOperateRequest.getDbankId(), fileOperateRequest.getIdList(),
				fileOperateRequest.getParentId());
		return HttpResult.ok();
	}

	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/findFileDownloadRecord")
	public HttpResult findFileDownloadRecord(@RequestParam String id, @RequestParam String dbankId) {
		return HttpResult.ok(fileDownloadHistoryService.findFileDownloadRecord(id));
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "修改了文件描述", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/addRemarks")
	public HttpResult addRemarks(@RequestParam String id, @RequestParam String dbankId, @RequestParam String remarks) {
		fileAuthManager.checkEdit(SecurityUtils.getUserId(), dbankId, id);

		FileInfo file = fileInfoService.addRemarks(id, remarks);
		return HttpResult.ok(file);
	}

	@OptLogDoc(objId = "#id", objCarrierId = "#dbankId", name = "评论了文档", optType = LogOptType.COMMENT, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/addComments")
	public HttpResult addComments(@RequestParam String id, @RequestParam String name,@RequestParam String dbankId,
			@RequestParam String comments) {
		return HttpResult.ok(fileInfoService.addComments(id,name, comments));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/getComments")
	public HttpResult getComments(@RequestParam String id, @RequestParam String dbankId) {
		return HttpResult.ok(fileQueryService.listComments(id));
	}

	@OptLogDoc(objId = "#file.id", objCarrierId = "#file.dbankId", name = "修改了文件名", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/renameFile")
	public HttpResult renameFile(@RequestBody FileInfo file) {
		fileAuthManager.checkEdit(SecurityUtils.getUserId(), file.getDbankId(), file.getId());
		fileInfoService.rename(file);
		return HttpResult.ok();
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "增加了文件标签", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/addaffix")
	public HttpResult addAffixs(@RequestBody FileAffixOptDTO dto) {
		fileAuthManager.checkEdit(SecurityUtils.getUserId(), dto.getDbankId(), dto.getFileId());
		return HttpResult.ok(fileInfoService.addAffix(dto.getFileId(), dto.getAffixs()));
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "删除了文件标签", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/removeaffix")
	public HttpResult removeAffixs(@RequestBody FileAffixOptDTO dto) {
		fileAuthManager.checkEdit(SecurityUtils.getUserId(), dto.getDbankId(), dto.getFileId());
		return HttpResult.ok(fileInfoService.removeAffix(dto.getFileId(), dto.getAffixs()));
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "关注了文件", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/focus")
	public HttpResult focus(@RequestBody Map<String, Object> param) {
		return HttpResult.ok(fileInfoService.focus(param.get("fileId").toString()));
	}

	@OptLogDoc(objId = "data.id", objCarrierId = "data.dbankId", name = "取消关注文件", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/unfocus")
	public HttpResult unFocus(@RequestBody List<String> fileIds) {
		return HttpResult.ok(fileInfoService.unFocus(fileIds));
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/share")
	public HttpResult share(@RequestBody PermissionSaveDTO dto) {
		for (String fileId : dto.getFiles()) {
			fileAuthManager.checkManage(SecurityUtils.getUserId(), dto.getDbankId(), fileId);
		}
		fileInfoService.share(dto);
		return HttpResult.ok();
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/unshare")
	public HttpResult unShare(@RequestBody FileShareDTO dto) {
		dto.getFileIds().forEach(fileId -> fileAuthManager.checkManage(SecurityUtils.getUserId(), dto.getDbankId(), fileId));
		fileInfoService.unShare(dto.getDbankId(), dto.getFileIds());
		return HttpResult.ok();
	}

	@OptLogDoc(objId = "#dto.![files]", objCarrierId = "#dto.dbankId", name = "对文件分类", optType = LogOptType.UPDATE, objType = LogBisType.file)
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/category")
	public HttpResult category(@RequestBody FileCategoryDTO dto) {
		dto.getFiles().forEach(fileId -> fileAuthManager.checkEdit(SecurityUtils.getUserId(), dto.getDbankId(), fileId));
		fileInfoService.category(dto.getDbankId(), dto.getFiles(), dto.getCategoryId());
		return HttpResult.ok();
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/publish")
	public HttpResult publish(@RequestBody FileOptDTO dto) {
		dto.getFiles().forEach(fileId -> fileAuthManager.checkManage(SecurityUtils.getUserId(), dto.getDbankId(), fileId));
		fileInfoService.publish(dto.getDbankId(), dto.getFiles());
		return HttpResult.ok();
	}

	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/unpublish")
	public HttpResult unPublish(@RequestBody FileOptDTO dto) {
		dto.getFiles().forEach(fileId -> fileAuthManager.checkManage(SecurityUtils.getUserId(), dto.getDbankId(), fileId));
		fileInfoService.unPublish(dto.getDbankId(), dto.getFiles());
		return HttpResult.ok();
	}

//	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping("/img")
	public void img(@RequestParam String storageType, @RequestParam String thumStorage1,
			@RequestParam String thumStorage2, HttpServletResponse response) {
//		return fileTransferService.images(storageType, thumStorage1, thumStorage2);
		response.setContentType(FileType.jpg.getMime());
		byte[] fileBytes = fileTransferService.images(storageType, thumStorage1, thumStorage2);
		FileUtils.download(response, fileBytes);
	}
	
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/analyse")
	public HttpResult analyse(@RequestParam String dbankId) {
		return HttpResult.ok(fileQueryService.analyse(dbankId));
	}
}
